home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-27 | 5.4 KB | 195 lines | [TEXT/CWIE] |
- //
- // CQD3DPane.cp
- //
- // class CQD3DPane [abstract]
- // A Pane for rendering a QuickDraw 3D view.
- //
- // by James Jennings
- // November 21, 1995
- //
-
- #include "CQD3DPane.h"
- #include "StQ3Disposer.h"
- #include "QD3D Debug Macros.h"
-
- #include <QD3DGeometry.h>
- #include <QD3DShader.h>
- #include <QD3DCamera.h>
- #include <QD3DLight.h>
- #include <QD3DGroup.h>
- #include <QD3DRenderer.h>
- #include <QD3DDrawContext.h>
- #include <QD3DMath.h>
- #include <QD3DTransform.h>
- #include <QD3DAcceleration.h> // defines kQAVendor_BestChoice
-
- CQD3DPane::CQD3DPane()
- : mView(0), mModel(0), mInterpolation(0), mBackFacing(0), mFillStyle(0)
- { // default constructor
- // Does nothing. Must call FinishCreate() later.
- }
-
- CQD3DPane::CQD3DPane(const CQD3DPane &inOriginal) : LPane(inOriginal),
- mView(0), mModel(0), mInterpolation(0), mBackFacing(0), mFillStyle(0)
- { // copy constructor
- mView = ::Q3Object_Duplicate(inOriginal.mView);
- ThrowIfNil_(mView);
- mModel = ::Q3Shared_GetReference(inOriginal.mModel);
- mInterpolation = ::Q3Shared_GetReference(inOriginal.mInterpolation);
- mBackFacing = ::Q3Shared_GetReference(inOriginal.mBackFacing);
- mFillStyle = ::Q3Shared_GetReference(inOriginal.mFillStyle);
- }
-
- CQD3DPane::CQD3DPane(LStream *inStream) : LPane(inStream),
- mView(0), mModel(0), mInterpolation(0), mBackFacing(0), mFillStyle(0)
- { // stream constructor
- // Does nothing. Must call FinishCreate() later.
- }
-
- CQD3DPane::~CQD3DPane()
- { // destructor
- if (mFillStyle) ::Q3Object_Dispose(mFillStyle);
- mFillStyle = 0;
- if (mBackFacing) ::Q3Object_Dispose(mBackFacing);
- mBackFacing = 0;
- if (mInterpolation) ::Q3Object_Dispose(mInterpolation);
- mInterpolation = 0;
- if (mModel) ::Q3Object_Dispose(mModel);
- mModel = 0;
- if (mView) ::Q3Object_Dispose(mView);
- mView = 0;
- }
-
- void
- CQD3DPane::FinishCreateSelf()
- { // We want to be able to override the helper methods, so we can't
- // put this stuff in the constructor.
- // This method creates a view, and adds the minimum required stuff.
- // Since the copy constructor might set each member, we check for 0
- // before creating each item.
-
- // Create view for QuickDraw 3D.
- if (mView==0)
- MakeView() ;
-
- // Create the main display group.
- if (mModel==0)
- MakeModel() ;
-
- // assorted styles
- if (mInterpolation==0)
- mInterpolation = ::Q3InterpolationStyle_New( GetInterpolationStyle() ) ;
- if (mBackFacing==0)
- mBackFacing = ::Q3BackfacingStyle_New( GetBackfacingStyle() ) ;
- if (mFillStyle==0)
- mFillStyle = ::Q3FillStyle_New( GetFillStyle() ) ;
- }
-
- void
- CQD3DPane::MakeView()
- { // A View must have a Camera, a Renderer, and a Draw Context.
- // The lights are optional.
- mView = ::Q3View_New();
- ThrowIfNil_(mView);
- MakeDrawContext();
- MakeRenderer();
- MakeCamera();
- MakeLightGroup();
- }
-
- void
- CQD3DPane::MakeDrawContext()
- { // Make and add a draw context to the current view.
- // (Perhaps we can init the TQ3DrawContextData struct from a resource.)
- // (The Mac part has to be done by hand.)
- TQ3DrawContextData data;
- TQ3MacDrawContextData macData;
- TQ3DrawContextObject theContext ;
-
- // Fill in draw context data.
- data.clearImageMethod = kQ3ClearMethodWithColor;
- GetClearImageColor(&(data.clearImageColor));
- data.paneState = kQ3False;
- data.maskState = kQ3False;
- data.doubleBufferState = kQ3True;
-
- macData.drawContextData = data;
-
- // this is the window associated with the view
- macData.window = (CGrafPtr) GetMacPort();
- macData.library = kQ3Mac2DLibraryNone;
- macData.viewPort = nil;
- macData.grafPort = nil;
-
- // Create draw context
- theContext = ::Q3MacDrawContext_New(&macData) ;
- ThrowIfNil_(theContext);
- StQ3Disposer con(theContext); // automatically dispose
-
- // Attach the draw context to our view.
- TQ3Status status = ::Q3View_SetDrawContext(mView, theContext);
- ThrowIfQ3Fail_(status);
- }
-
- void
- CQD3DPane::MakeRenderer()
- {
- TQ3RendererObject theRenderer;
- TQ3Status status;
-
- theRenderer = ::Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
- ThrowIfNil_(theRenderer);
- StQ3Disposer ren(theRenderer); // automatically dispose
-
- // attach to the view
- status = ::Q3View_SetRenderer(mView, theRenderer);
- ThrowIfQ3Fail_(status);
-
- // these two lines set us up to use the best possible renderer,
- // including hardware if it is installed.
- ::Q3InteractiveRenderer_SetDoubleBufferBypass (theRenderer, kQ3True);
- ::Q3InteractiveRenderer_SetPreferences(theRenderer, kQAVendor_BestChoice, 0);
-
- }
-
- void
- CQD3DPane::DrawSelf()
- { // Your basic submitting loop.
- TQ3Status status;
- TQ3ViewStatus viewStatus;
- status = ::Q3View_StartRendering(mView);
- ThrowIfQ3Fail_(status);
- try {
- do {
- // Don't throw anything from inside this loop, else
- // ::Q3View_EndRendering() never gets called.
- // (Can we fix that with a stack object?)
- status = SubmitScene();
- viewStatus = ::Q3View_EndRendering(mView);
- } while ( viewStatus == kQ3ViewStatusRetraverse );
- }
- catch (...) {
- // if something threw an exception, we need to stop rendering
- status = ::Q3View_Cancel(mView);
- throw;
- }
- ThrowIfQ3Any_();
- }
-
- TQ3Status
- CQD3DPane::SubmitScene()
- { // As recommended in develop 23, we separate the body
- // of the Submit loop so it may be used for other things
- // than rendering.
- // There is no model yet, but this code could be called from
- // a sub-class which also submits a model.
- TQ3Status status;
- status = ::Q3Style_Submit( mInterpolation, mView );
- if (status==kQ3Failure) return status;
- status = ::Q3Style_Submit( mBackFacing, mView );
- if (status==kQ3Failure) return status;
- status = ::Q3Style_Submit( mFillStyle, mView );
- return status;
- }
-
-